import json
import traceback

from django.utils import timezone
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import status, viewsets, filters
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ViewSet
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.authentication import BasicAuthentication
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework_jwt.views import ObtainJSONWebToken
from sts.sts import Sts

from common.img_manager import COS_SECRET_ID, SECRET_KEY, ObjectCloudSave,\
    QCLOUD_COS_BUCKET, AWS_S3_REGION_NAME
from account.models import User, OrgLabel, OrgStructure
from account.serializers import FetchAccountUserSerializer
from config.settings.base import logger


class ShutongObtainJSONWebToken(ObtainJSONWebToken):

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            userObj = serializer.object.get('user') or request.user
            userObj.last_login = timezone.datetime.now()
            userObj.save()
        return super(ShutongObtainJSONWebToken, self).post(request, *args, **kwargs)


class UserViewSet(viewsets.ReadOnlyModelViewSet):
    """
    用户列表
    """
    filter_backends = (DjangoFilterBackend, filters.SearchFilter,)
    filter_fields = ('username', 'nickname', 'org')
    search_fields = ('username', 'nickname')
    queryset = User.objects.all()
    serializer_class = FetchAccountUserSerializer

    def get_permissions(self):
        if self.action == "get_user_test":
            self.permission_classes = [AllowAny]
        return [permission() for permission in self.permission_classes]

    @action(methods=['POST'], detail=False)
    def dd_user_list(self, request):
        user_ids = request.data.get('user_ids')
        users = []
        if user_ids:
            try:
                if isinstance(user_ids, str):
                    user_ids = json.loads(user_ids)
                queryset = self.filter_queryset(self.get_queryset())
                user_qs = queryset.filter(username__in=user_ids)
                users = FetchAccountUserSerializer(user_qs, many=True).data
            except Exception:
                logger.error(traceback.format_exc())
        return Response(users)

    @action(methods=['get'], detail=False)
    def iam(self, request, pk=None):
        data = self.get_serializer(request.user).data
        return Response(data)

    @action(methods=['get'], detail=False)
    def get_users(self, request, pk=None):
        data = {}
        ret = []
        try:
            label_ids_str = request.query_params.get('label_ids') or ''
            org_ids_str = request.query_params.get('org_ids') or ''
            if label_ids_str:
                abel_ids = label_ids_str.split(',')
                use_qs = User.objects.filter(orglabel__label_id__in=abel_ids)
            elif org_ids_str:
                obj_ids = org_ids_str.split(',')
                use_qs = User.objects.filter(org__department_id__in=obj_ids)
            use_qs = use_qs.filter(is_active=True)
            ret = self.get_serializer(use_qs, many=True).data
            data['result'] = 'info'
            data['users'] = ret
            data['msg'] = ''
        except Exception:
            logger.error(traceback.format_exc())
            data['result'] = 'error'
            data['users'] = ret
            data['msg'] = '参数错误！'
        return Response(data=data)

    @action(methods=['get'], detail=False)
    def get_user_test(self, request, pk=None):
        """
        test
        todo: 待删除
        :return:
        """
        qs = self.filter_queryset(self.get_queryset()).values('id', 'nickname')
        page = self.paginate_queryset(qs)
        if page is not None:
            return self.get_paginated_response(page)
        return Response(qs)


class StsAuth(APIView):
    permission_classes = (IsAuthenticated, )
    # permission_classes = ()

    def get(self, request, *args, **kwargs):
        # 获取 token
        config = {
            # 临时密钥有效时长，单位是秒
            'duration_seconds': 1800,
            # 固定密钥
            'secret_id': COS_SECRET_ID,
            # 固定密钥
            'secret_key': SECRET_KEY,
            # 是否需要设置代理
            # 'proxy': {
            #     'http': 'XXX',
            #     'https': 'XXX'
            # },
            # 换成你的 bucket
            'bucket': QCLOUD_COS_BUCKET,
            # 换成 bucket 所在地区
            'region': AWS_S3_REGION_NAME,
            # 这里改成允许的路径前缀，可以根据自己网站的用户登录态判断允许上传的具体路径
            # 例子： a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
            'allow_prefix': 'media/*',
            # 密钥的权限列表。简单上传和分片需要以下的权限，其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
            'allow_actions': [
                # 删除单个
                "name/cos:DeleteObject",
                # 简单上传
                'name/cos:PutObject',
                # 表单上传
                'name/cos:PostObject',
                # 分片上传： 初始化分片
                'name/cos:InitiateMultipartUpload',
                # 分片上传： 查询 bucket 中未完成分片上传的UploadId
                "name/cos:ListMultipartUploads",
                # 分片上传： 查询已上传的分片
                "name/cos:ListParts",
                # 分片上传： 上传分片块
                "name/cos:UploadPart",
                # 分片上传： 完成分片上传
                "name/cos:CompleteMultipartUpload"
            ]
        }
        sts = Sts(config)
        response = sts.get_credential()
        print('get data : ' + json.dumps(dict(response), indent=4))
        token = response["credentials"]["sessionToken"]
        tmp_secret_id = response["credentials"]["tmpSecretId"]
        tmp_secret_key = response["credentials"]["tmpSecretKey"]

        # 获取 authorization
        method = request.GET.get('method')
        pathname = request.GET.get('pathname')
        authorization = ObjectCloudSave.get_auth(method, pathname, tmp_secret_id, tmp_secret_key)

        # 组装返回结果
        response = {
            'Authorization': authorization,
            'XCosSecurityToken': token,
            'Prefix': ObjectCloudSave.get_root_url(),
        }

        return Response(response)
